package com.ticket.web.controller.yanchu;

import java.math.BigDecimal;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ticket.common.exception.ServiceException;
import com.ticket.system.domain.vo.RechargeParamVo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;

import io.swagger.annotations.Api;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ticket.common.annotation.Log;
import com.ticket.common.core.controller.BaseController;
import com.ticket.common.core.domain.AjaxResult;
import com.ticket.common.enums.BusinessType;
import com.ticket.system.domain.YanchuStorageCrad;
import com.ticket.system.service.IYanchuStorageCradService;
import com.ticket.common.utils.poi.ExcelUtil;
import com.ticket.common.core.page.TableDataInfo;

/**
 * 储存卡信息（包含绑定信息）Controller
 * 
 * @author ruoyi
 * @date 2023-12-12
 */
@RestController
@RequestMapping("/system/crad")
@Api("储存卡信息")
public class YanchuStorageCradController extends BaseController
{
    @Autowired
    private IYanchuStorageCradService yanchuStorageCradService;
    @Resource
    private WxPayService wxPayService;

    /**
     * 查询储存卡信息（包含绑定信息）列表
     */
    @PreAuthorize("@ss.hasPermi('system:crad:list')")
    @GetMapping("/list")
    public TableDataInfo list(YanchuStorageCrad yanchuStorageCrad)
    {
        startPage();
        List<YanchuStorageCrad> list = yanchuStorageCradService.selectYanchuStorageCradList(yanchuStorageCrad);
        return getDataTable(list);
    }

    /**
     * 导出储存卡信息（包含绑定信息）列表
     */
    @PreAuthorize("@ss.hasPermi('system:crad:export')")
    @Log(title = "储存卡信息（包含绑定信息）", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, YanchuStorageCrad yanchuStorageCrad)
    {
        List<YanchuStorageCrad> list = yanchuStorageCradService.selectYanchuStorageCradList(yanchuStorageCrad);
        ExcelUtil<YanchuStorageCrad> util = new ExcelUtil<YanchuStorageCrad>(YanchuStorageCrad.class);
        util.exportExcel(response, list, "储存卡信息（包含绑定信息）数据");
    }

    /**
     * 获取储存卡信息（包含绑定信息）详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:crad:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(yanchuStorageCradService.selectYanchuStorageCradById(id));
    }

    /**
     * 新增储存卡信息（包含绑定信息）
     */
    @PreAuthorize("@ss.hasPermi('system:crad:add')")
    @Log(title = "储存卡信息（包含绑定信息）", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody YanchuStorageCrad yanchuStorageCrad)
    {
        return toAjax(yanchuStorageCradService.insertYanchuStorageCrad(yanchuStorageCrad));
    }

    /**
     * 修改储存卡信息（包含绑定信息）
     */
    @PreAuthorize("@ss.hasPermi('system:crad:edit')")
    @Log(title = "储存卡信息（包含绑定信息）", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody YanchuStorageCrad yanchuStorageCrad)
    {
        return toAjax(yanchuStorageCradService.updateYanchuStorageCrad(yanchuStorageCrad));
    }

    /**
     * 删除储存卡信息（包含绑定信息）
     */
    @PreAuthorize("@ss.hasPermi('system:crad:remove')")
    @Log(title = "储存卡信息（包含绑定信息）", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(yanchuStorageCradService.deleteYanchuStorageCradByIds(ids));
    }

    /**
     * 会员充值
     */
    @ApiOperation("会员充值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rechargeParamVo", value = "充值请求对象", dataType = "RechargeParamVo", dataTypeClass = RechargeParamVo.class)
    })
    @Log(title = "会员充值", businessType = BusinessType.INSERT)
    @PostMapping("/recharge")
    public AjaxResult recharge(@RequestBody @Valid RechargeParamVo rechargeParamVo){
        try {
            return success(yanchuStorageCradService.recharge(rechargeParamVo.getRuleId(),rechargeParamVo.getAmount()));
        } catch (ServiceException se){
            logger.error("充值失败！", se);
            return AjaxResult.error(se.getMessage());
        } catch (Exception e) {
            logger.error("充值失败！", e);
            return AjaxResult.error("充值失败，请稍后重试！");
        }
    }

    /**
     * 会员充值回调
     */
    @Log(title = "会员充值回调", businessType = BusinessType.INSERT)
    @PostMapping("/rechargeNotify/forAllUser")
    public String rechargeHSNotify(HttpServletRequest request){
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);

            // 加入自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用
            String outTradeNo = result.getOutTradeNo();
            String transactionId = result.getTransactionId();
            String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
            yanchuStorageCradService.notifyRecharge(outTradeNo,new BigDecimal(totalFee),transactionId);
            return WxPayNotifyResponse.success("处理成功!");
        } catch (Exception e) {
            logger.error("微信回调结果异常", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }
}
